<template>
  <div class="search">
    <div class="searchInfo"></div>
    <a-button type="primary" @click="toAdd">
      <template #icon><plus-outlined /> </template>
    </a-button>
  </div>
  <a-table
    :dataSource="tableData.data"
    :columns="tableData.listColumns"
    :pagination="false"
    bordered
  >
    <template #bodyCell="{ column, index, record }">
      <template v-if="column.dataIndex === 'index'">
        {{ index + 1 }}
      </template>
      <template v-if="column.dataIndex === 'operation'">
        <a @click="toUpdate(record)">编辑</a>
        <a style="padding-left: 10px" @click="toDelete(record, 1)">删除</a>
        <a style="padding-left: 10px" @click="toDelete(record, 2)">删除命名空间</a>
        <a style="padding-left: 10px" @click="toDelete(record, 3)">删除项目配置</a>
        <a style="padding-left: 10px" @click="toCopy(record, 1)">克隆环境配置</a>
        <a style="padding-left: 10px" @click="toCopy(record, 2)">克隆项目配置</a>
        <a style="padding-left: 10px" @click="initNamespace(record)">初始化</a>
      </template>
    </template>
  </a-table>
  <a-pagination
    v-model:current="query.currentPage"
    :total="tableData.total"
    @change="pageChange"
    show-less-items
    :show-total="(total) => `共 ${total} 条`"
  />

  <a-modal
    v-model:visible="addForm.visible"
    title="新增"
    okText="确定"
    cancelText="取消"
    width="30%"
    :maskClosable="false"
    centered
    @ok="add"
    @cancel="cancelAdd"
  >
    <a-form
      :model="addForm.data"
      name="addForm"
      ref="addFormRef"
      v-bind="formLayout"
    >
      <a-form-item
        label="环境"
        name="env"
        :rules="[{ required: true, message: '请输入环境' }, { message: '只能输入(中文,字母,数字),最大长度为20', pattern: /^[\u4e00-\u9fa5a-zA-Z0-9]{1,20}$/ }]"
      >
        <a-input placeholder="中文,字母,数字,最大长度为20" v-model:value="addForm.data.env" />
      </a-form-item>
      <a-form-item
        label="命名空间"
        name="namespace"
        :rules="[{ required: true, message: '请输入命名空间' }, { message: '只能输入(小写字母,数字,_),最大长度为20', pattern: /^[a-z0-9_]{1,20}$/ }]"
      >
        <a-input placeholder="小写字母,数字,下划线,最大长度为20" v-model:value="addForm.data.namespace" />
      </a-form-item>
    </a-form>
  </a-modal>
  <a-modal
    v-model:visible="updateForm.visible"
    title="修改"
    okText="确定"
    cancelText="取消"
    width="30%"
    :maskClosable="false"
    centered
    @ok="update"
    @cancel="cancelUpdate"
  >
    <a-form
      :model="updateForm.data"
      name="updateForm"
      ref="updateFormRef"
      v-bind="formLayout"
    >
      <a-form-item
        label="环境"
        name="env"
        :rules="[{ required: true, message: '请输入环境' }, { message: '只能输入中文,字母,数字,最大长度为20', pattern: /^[\u4e00-\u9fa5a-zA-Z0-9]{1,20}$/ }]"
      >
        <a-input v-model:value="updateForm.data.env" />
      </a-form-item>
    </a-form>
  </a-modal>
  <a-modal
    v-model:visible="copyForm.visible"
    title="环境克隆"
    okText="确定"
    cancelText="取消"
    width="30%"
    :maskClosable="false"
    centered
    @ok="copy"
    @cancel="cancelCopy"
  >
    <a-form
      :model="copyForm.data"
      name="copyForm"
      ref="copyFormRef"
      v-bind="formLayout"
    >
      <a-form-item
        v-if="copyForm.type === 1"
        label="新环境"
        name="newEnv"
        :rules="[{ required: true, message: '请输入新环境' }, { message: '只能输入中文,字母,数字,最大长度为20', pattern: /^[\u4e00-\u9fa5a-zA-Z0-9]{1,20}$/ }]"
      >
        <a-input v-model:value="copyForm.data.newEnv" />
      </a-form-item>
      <a-form-item
        v-if="copyForm.type === 1"
        label="新命名空间"
        name="newNamespace"
        :rules="[{ required: true, message: '请输入新命名空间' }, { message: '只能输入(小写字母,数字,_),最大长度为20', pattern: /^[a-z0-9_]{1,20}$/ }]"
      >
        <a-input v-model:value="copyForm.data.newNamespace" />
      </a-form-item>
      <a-form-item
        v-if="copyForm.type === 2"
        label="目标环境"
        name="targetId"
        :rules="[{ required: true, message: '请选择环境' }]"
      >
        <a-select
          v-model:value="copyForm.data.targetId"
          :options="copyForm.envData"
          :fieldNames="copyForm.envFieldNames"
        ></a-select>
      </a-form-item>
      <a-tree
        v-if="copyForm.type === 2"
        v-model:checkedKeys="copyForm.checkedKeys"
        checkable
        :tree-data="copyForm.treeData"
      >
        <template #title="{ title, key }">
          <span v-if="key === '0-0-1-0'" style="color: #1890ff">{{ title }}</span>
          <template v-else>{{ title }}</template>
        </template>
      </a-tree>
    </a-form>
  </a-modal>
  <a-modal
    v-model:visible="deleteForm.visible"
    :title="deleteForm.title"
    okText="确定"
    cancelText="取消"
    width="30%"
    :maskClosable="false"
    centered
    @ok="del"
    @cancel="cancelDelete"
  >
    <p style=''>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{deleteForm.content}}</p>
  </a-modal>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { reactive, ref } from "@vue/reactivity";
import {
  PlusOutlined,
  ReloadOutlined,
  SearchOutlined,
} from "@ant-design/icons-vue";
import { envApi, projectApi } from "@/api/devcloudApi";
import { message } from "ant-design-vue";
import { clearObject, clone, deleteKeyIgnore } from "@/util/utils";

export default defineComponent({
  name: "env",
  components: {
    ReloadOutlined,
    SearchOutlined,
    PlusOutlined,
  },
  setup() {
    const returnObj: any = {}

    const formLayout = {
      labelCol: { span: 6 },
      wrapperCol: { span: 18 },
    }

    // ------------ 查询条件 ------------------------
    const query = reactive({
      env: "",
      namespace: "",
      currentPage: 1,
      pageSize: 10,
    });

    const search = () => {
      query.currentPage = 1;
      query.pageSize = 10;
      list();
    }

    const initQuery = () => {
      query.env = "";
      query.namespace = "";
      query.currentPage = 1;
      query.pageSize = 10;
    }

    const reload = () => {
      initQuery();
      list();
    }

    returnObj.query = query;
    returnObj.search = search;
    returnObj.reload = reload;

    // ------------ 添加弹框 ------------------------
    const addFormRef = ref();
    const addForm = reactive({
      visible: false,
      data: {},
    });

    const initAddForm = () => {}

    const toAdd = async () => {
      initAddForm();
      addForm.visible = true;
    }

    const cancelAdd = () => {
      addFormRef.value.resetFields();
      addForm.visible = false;
    }

    const add = () => {
      addFormRef.value.validateFields().then(async () => {
        const res = await envApi.insert(addForm.data);
        if (res.success) {
          message.success("添加成功");
          reflush();
          cancelAdd();
        }
      });
    }

    returnObj.addFormRef = addFormRef;
    returnObj.addForm = addForm;
    returnObj.toAdd = toAdd;
    returnObj.cancelAdd = cancelAdd;
    returnObj.add = add;

    // ------------ 修改弹框 ------------------------
    const updateFormRef = ref();
    const updateForm = reactive({
      visible: false,
      data: {},
    });

    const initUpdateForm = (item: any) => {
      const obj = clone(item);
      deleteKeyIgnore(obj, "id", "env", "namespace");
      updateForm.data = obj;
    }

    const toUpdate = (item: any) => {
      initUpdateForm(item);
      updateForm.visible = true;
    }

    const cancelUpdate = () => {
      updateFormRef.value.resetFields();
      updateForm.visible = false;
    }

    const update = () => {
      updateFormRef.value.validateFields().then(async () => {
        const res = await envApi.update(updateForm.data);
        if (res.success) {
          message.success("更新成功");
          reflush();
          cancelUpdate();
        }
      });
    }

    returnObj.updateFormRef = updateFormRef;
    returnObj.updateForm = updateForm;
    returnObj.toUpdate = toUpdate;
    returnObj.cancelUpdate = cancelUpdate;
    returnObj.update = update;

    // ------------- 复制 ------------------------------
    const copyFormRef = ref();
    const copyForm:any = reactive({
      visible: false,
      type: 1,
      data: {
        id: "",
        targetId: '',
        newEnv: "",
        newNamespace: '',
      },
      envFieldNames:{
        value: "id",
        label: "env",
      },
      envData:[],
      checkedKeys:[],
      treeData:[],
      allIdData: [],
      projectIdData: []
    });

    const listProductProjectTree = async () => {
      const res = await projectApi.listProductProjectTree({envId:copyForm.data.id})
      if(res.success){
        if(!res.result.length){
          message.warn("当前环境没有可复制项目")
        }
        copyForm.treeData = res.result
        const allIdData: string[] = []
        const projectIdData: string[] = []
        copyForm.treeData.forEach((item:any)=>{
          allIdData.push(item.key)
          item.children?.forEach((item2:any) => {
            allIdData.push(item2.key)
            projectIdData.push(item2.key)
          })
        })
        copyForm.allIdData = allIdData
        copyForm.projectIdData = projectIdData
      }
    }

    const initCopyForm = async () => {
      if(copyForm.type === 1 ){
        copyForm.data.newEnv = "";
        copyForm.data.newNamespace = "";
      }else if(copyForm.type == 2){
        await listProductProjectTree()
        copyForm.checkedKeys = copyForm.allIdData
        copyForm.envData = tableData.data.filter((item:any)=>{
          if(item.id === copyForm.data.id){
            return false
          }
          return true
        })
      }
    }

    const toCopy = async (item: any, type: number) => {
      copyForm.type = type
      copyForm.data.id = item.id;
      await initCopyForm();
      if(copyForm.type == 2 && !copyForm.treeData.length){
        return
      }
      copyForm.visible = true;
    }

    const copy = () => {
      if(copyForm.type === 1 ){
        copyEnvConfig()
      }else if(copyForm.type == 2){
        copyProjectConfig()
      }
    }

    const copyEnvConfig = () => {
      copyFormRef.value.validateFields().then(async () => {
        const res = await envApi.copyEnvConfig(copyForm.data.id, copyForm.data.newEnv, copyForm.data.newNamespace);
        if (res.success) {
          message.success("复制环境配置成功");
          reflush();
          cancelCopy();
        }
      });
    }

    const copyProjectConfig = () => {
      const projectIds = copyForm.checkedKeys.filter((key:string)=>{
        if(copyForm.projectIdData.includes(key)){
          return true
        }
        return false
      })
      copyFormRef.value.validateFields().then(async () => {
        const res = await envApi.copyProjectConfig(copyForm.data.id, copyForm.data.targetId, projectIds);
        if (res.success) {
          message.success("复制项目配置成功");
          reflush();
          cancelCopy();
        }
      });
    }

    const cancelCopy = () => {
      copyFormRef.value.resetFields();
      copyForm.visible = false;
    }

    returnObj.copyFormRef = copyFormRef;
    returnObj.copyForm = copyForm;
    returnObj.toCopy = toCopy;
    returnObj.cancelCopy = cancelCopy;
    returnObj.copy = copy;

    // ------------ 表格 ------------------------
    const tableData = reactive({
      total: 0,
      data: [],
      listColumns: [
        {
          title: "序号",
          dataIndex: "index",
          align: "center",
          width: "50px",
        },
        {
          title: "环境",
          dataIndex: "env",
          key: "env",
          width: "100px",
          align: "center",
        },
        {
          title: "命名空间",
          dataIndex: "namespace",
          key: "namespace",
          width: "100px",
          align: "center",
        },
        {
          title: "操作",
          dataIndex: "operation",
          width: "150px",
          align: "center",
        },
      ],
    });

    const pageChange = (page: number, pageSize: number) => {
      query.currentPage = page;
      query.pageSize = pageSize;
      list();
    }
    returnObj.pageChange = pageChange;

    const list = async () => {
      clearObject(query);
      const res = await envApi.page(query);
      if (res.success) {
        tableData.data = res.result;
        tableData.total = res.count;
      }
    }

    const reflush = () => {
      initQuery();
      list();
    }

    const deleteForm = reactive({
      visible: false,
      title: '',
      content: '',
      type: 0,
      id: ''
    })

    const toDelete = (record:any, type:number) => {
      if(1 ===type){
        deleteForm.type = 1
        deleteForm.content = '是否删除所有 [' + record.env +'] 环境数据, 包括所有环境配置, 项目配置, k8s正在运行程序'
        deleteForm.title = '删除配置信息'
      }else if(2 ===type){
        deleteForm.type = 2
        deleteForm.content = '是否删除k8s中 [' + record.namespace +'] 的命名空间(包括namespace, deploy, pod, servie, ingress等...)以及jenkins中的job'
        deleteForm.title = '删除命名空间'
      }else if(3 ===type){
        deleteForm.type = 3
        deleteForm.content = '是否删除发布系统中 [' + record.env +'] 环境所有项目, 配置, 运行信息'
        deleteForm.title = '删除项目配置'
      }else{
        return
      }
      deleteForm.id = record.id
      deleteForm.visible = true
    }

    const cancelDelete = () => {
      deleteForm.id = ''
      deleteForm.type = 0
      deleteForm.content = ''
      deleteForm.title = ''
      deleteForm.visible = false
    }


    const del = async () => {
      if(1 === deleteForm.type){
        const res = await envApi.delete(deleteForm.id);
        if (res.success) {
          message.success(deleteForm.title + '成功(k8s删除命令空间可能需要时间)');
          reflush();
        }
      }else if(2 === deleteForm.type){
        const res = await envApi.deleteNamespace(deleteForm.id);
        if (res.success) {
          message.success(deleteForm.title + '成功(k8s删除命令空间可能需要时间)')
        }
      }else if(3 === deleteForm.type){
        const res = await envApi.deleteProjectInfo(deleteForm.id);
        if (res.success) {
          message.success(deleteForm.title + '成功');
        }
      }else{
        return
      }
      cancelDelete()
    }

    const initNamespace = async (item: any) => {
      const res = await envApi.initNamespace(item.id);
      if (res.success) {
        message.success("初始化成功");
        reflush();
      }
    }

    returnObj.tableData = tableData;
    returnObj.del = del;
    returnObj.toDelete = toDelete
    returnObj.cancelDelete = cancelDelete
    returnObj.deleteForm = deleteForm
    returnObj.initNamespace = initNamespace

    const state = reactive({});

    // ------------查询------------------

    // --------------初始化--------------------------

    const initData = () => {
      reflush();
    }

    initData();

    return {
      ...returnObj,
      formLayout,
      state,
    }
  },
});
</script>

<style lang="less" scoped>
.search {
  display: flex;
  justify-content: space-between;
  padding: 40px 90px 0 50px;
}
.ant-table-wrapper {
  margin: 40px;
}

.searchInfo {
  width: 80%;
  display: flex;

  .ant-input {
    width: 180px;
    margin: 0 10px;
  }
  .ant-select {
    width: 180px;
    margin: 0 10px;
  }
  .search-btn {
    margin: 0 10px;
  }
}
.ant-pagination {
  padding-top: 20px;
}
.ant-modal {
  .ant-input {
    width: 280px;
  }
  .ant-select {
    width: 280px;
  }
  .ant-picker {
    width: 200px;
  }
  .ant-input-number {
    width: 100px;
  }
}
</style>